<?php
/**
 * @author spenceryg
 * @date 2022/11/25
 * @time 12:44 下午
 * @focus love & life
 */

namespace app\admin\controller\sys\business;

use app\admin\controller\sys\AdminUser;
use app\admin\controller\sys\model\AdminNodeModel;
use app\admin\controller\sys\model\AdminRoleAccessModel;
use app\admin\controller\sys\model\AdminRoleModel;
use app\admin\controller\sys\model\AdminRoleNodeModel;
use app\admin\controller\sys\model\AdminUserModel;
use app\admin\controller\sys\validate\AdminUserValidate;
use app\admin\controller\sys\validate\LoginValidate;
use app\admin\service\AdminRole;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Db;

class AdminUserBusiness
{
    /**
     * getList
     * @return array
     * @throws DbException
     */
    public static function getList(): array
    {
        $data = AdminUserModel::order('sort asd')->paginate(10);
        return [
            'data' => $data,
            'paginate' => $data ? $data->render() : ''
        ];
    }




    public static function login($data)
    {
        validate(LoginValidate::class)->check($data);
        self::checkLogin($data['username'], $data['password']);
    }


    /**
     * checkLogin
     * @param $username
     * @param $password
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public static function checkLogin($username, $password)
    {
        $user_data = AdminUserModel::where('username', $username)->find();
        if ($user_data) {
            $real_password = md5($password.'_spencer_salt');
            if ($real_password != $user_data['password']) {
                throw new ValidateException('用户密码错误');
            }

            //更新用户登录时间 ip
            $user_data->last_login_time = time();
            $user_data->last_login_ip = request()->ip();
            $user_data->save();

            session(config('admin.admin_session'), $user_data);
            if (config('member.role_type')) {
                $admin_role_id = AdminUserModel::where('admin_user_id', $user_data['id'])->order('id asc')->value('admin_role_id');
                $admin_role_data =  AdminRoleModel::with(['adminAccess', 'adminNode'])->where('id', $admin_role_id)->find();
                session(config('admin.role_session'), $admin_role_data);
            }
            session(config('admin.node_session'), self::getMenu($user_data['id']));
            session(config('admin.access_session'), self::getAccess($user_data['id']));
        } else {
            throw new ValidateException('用户不存在');
        }
    }


    /**
     * 添加用户
     * @param $data
     * @return mixed
     */
    public static function addUser($data)
    {
        validate(AdminUserValidate::class)->check($data);
        $role_arr = $data['role'];
        unset($data['role']);
        $data['password'] = md5($data['password'].'_spencer_salt');
        $admin_user  = AdminUserModel::create($data);
        $admin_user->level = AdminUserModel::getLevel($admin_user);
        if (!$admin_user->sort) {
            $admin_user->sort = AdminUserModel::getSort($admin_user);
        }
        $admin_user->save();
        $save['admin_user_id'] = $admin_user->id;
        foreach ($role_arr as $role) {
            $save['admin_role_id'] = $role;
            Db::name('admin_role_user')->save($save);
        }
        return $admin_user->id;
    }

    /**
     * 更新用户
     * @param $data
     * @throws Exception
     */
    public static function updateUser($data)
    {
        $admin_user = AdminUserModel::find($data['id']);
        if ($admin_user['is_super']) {
            validate(AdminUserValidate::class)->scene('update_super')->check($data);
        } else {
            validate(AdminUserValidate::class)->scene('update')->check($data);
        }
        $role_arr = $data['role'];
        unset($data['role']);
        if ($data['password']) {
            $data['password'] = md5($data['password'].'_spencer_salt');
        } else {
            unset($data['password']);
        }
        $admin_user = AdminUserModel::update($data);
        $admin_user->level = AdminNodeModel::getLevel($admin_user);
        if (!$admin_user->sort) {
            $admin_user->sort = AdminUserModel::getSort($admin_user);
        }
        $admin_user->save();
        $save['admin_user_id'] = $data['id'];
        Db::name('admin_role_user')->where('admin_user_id', $data['id'])->delete();
        foreach ($role_arr as $role) {
            $save['admin_role_id'] = $role;
            Db::name('admin_role_user')->save($save);
        }
    }


    /**
     * 获取菜单
     * @param $id
     * @return array|string
     */
    public static function getMenu($id)
    {
        $user = AdminUserModel::find($id);
        $is_super = $user->is_super;
        if ($is_super) {
            return '*';
        }
//        $roles = $user->adminRole->toArray();
        $res = [];
        $role_type = config('admin.role_type');
        if (!$role_type) {
            foreach ($user->adminRole as $role) {
                $node_id_arr = AdminRoleNodeModel::where('admin_role_id', $role->id)->column('admin_node_id');
//                $node_id_arr =  array_column($role->adminNode->toArray(), 'id');
                $res = array_merge($res, $node_id_arr);
            }
        } else {
            $role = session(config('admin.role_session'));
            $node_id_arr = AdminRoleNodeModel::where('admin_role_id', $role->id)->column('admin_node_id');
//            $role  =  AdminRoleModel::with(['adminAccess', 'adminNode'])->where('id', $role->id)->find();
//            $res = array_column($role->adminNode->toArray(), 'id');
        }
        return array_unique($res);
    }

    /**
     * 获取权限
     * @param $id
     * @return array|string
     */
    public static function getAccess($id)
    {
        $user = AdminUserModel::find($id);
        $is_super = $user->is_super;
        if ($is_super) {
            return '*';
        }
//        $roles = $user->adminRole->toArray();
        $res = [];
        $role_type = config('admin.role_type');
        if (!$role_type) {
            foreach ($user->adminRole as $role) {
                foreach ($role->adminAccess as $access) {
                    $path = $access['path'];
                    $res = array_merge($res, explode('|', trim($path, '|')));
                }
            }
        } else {
            $role = session(config('admin.role_session'));
            $role = (new AdminRole())->getFullById($role->id);
            $access_arr = $role->adminAccess->toArray();
            foreach ($access_arr as $access) {
                $path = $access['path'];
                $res = array_merge($res, explode('|', trim($path, '|')));
            }
        }

        return array_unique($res);
    }

    /**
     * 删除
     * @param $id
     * @throws Exception
     */
    public function treeDelete($id)
    {
        $data = $this->getById($id);
        if ($data['forefathers']) {
            $pid_arr = explode(',', trim($data['forefathers'], ','));
            foreach ($pid_arr as $pid) {
                $parent_data = $this->getById($pid)->getData();
                $parent_sons = explode(',', trim($parent_data['sons'], ','));
                foreach ($parent_sons as $k=>$v) {
                    if ($v == $id) {
                        unset($parent_sons[$k]);
                    }
                }
                if ($parent_sons) {
                    $parent_data['sons'] = ',' .  implode(',', $parent_sons) . ',';
                } else {
                    $parent_data['sons'] = null;
                }

                $parent_descendants = explode(',', trim($parent_data['descendants'], ','));
                foreach ($parent_descendants as $k=>$v) {
                    if ($v == $id) {
                        unset($parent_descendants[$k]);
                    }
                }
                if ($parent_descendants) {
                    $parent_data['descendants'] = ',' .  implode(',', $parent_descendants) . ',';
                } else {
                    $parent_data['descendants'] = null;
                }
                $this->update($parent_data);
            }
        }
        $this->delete($id);
        $son_ids = $data['descendants'] ? explode(",", trim($data['descendants'], ',')) : [];
        foreach ($son_ids as $son_id) {
            $this->delete($son_id);
        }
    }


    /**
     * 更换角色
     * @param $user_id
     * @param $role_id
     * @throws Exception
     */
    public function changeRole($user_id, $role_id)
    {
        $user = AdminUserModel::find($user_id);
        $roles_can_change = array_column($user->adminRole->toArray(), 'id');
        if (in_array($role_id, $roles_can_change)) {
            if ($role_id === session(config('admin.role_session'))->id) {
                throw new Exception('当前角色无需切换！');
            } else {
                $role_data =  AdminRoleModel::with(['adminAccess', 'adminNode'])->where('id', $role_id)->find();
                ;
                session(config('admin.role_session'), $role_data);
                session(config('admin.node_session'), self::getMenu($user_id));
                session(config('admin.access_session'), self::getAccess($user_id));
            }
        } else {
            throw new Exception('非法角色');
        }
    }
}
